package handling.channel.handler;

import server.maps.AnimatedMapleMapObject;
import server.movement.LifeMovement;
import server.movement.LifeMovementFragment;
import server.movement.StaticLifeMovement;
import tools.data.LittleEndianAccessor;

import java.awt.*;
import java.util.ArrayList;
import java.util.List;

public class MovementParse {
    public static List<LifeMovementFragment> parseMovement(LittleEndianAccessor lea, int kind) {
        List<LifeMovementFragment> res = (List<LifeMovementFragment>) new ArrayList();
        byte numCommands = lea.readByte();
        if (numCommands <= 0) {
            return null;
        }
        for (byte i = 0; i < numCommands; ++i) {
            byte command = lea.readByte();
            switch (command) {
                case 0:
                case 5:
                case 15:
                case 17: {
                    short xpos = lea.readShort();
                    short ypos = lea.readShort();
                    short xwobble = lea.readShort();
                    short ywobble = lea.readShort();
                    short unk = lea.readShort();
                    short fh = 0;
                    if (command == 15) {
                        fh = lea.readShort();
                    }
                    byte newstate = lea.readByte();
                    short duration = lea.readShort();
                    StaticLifeMovement mov = new StaticLifeMovement((int) command, new Point((int) xpos, (int) ypos), (int) duration, (int) newstate, (int) unk);
                    mov.setUnk(unk);
                    mov.setFh(fh);
                    mov.setPixelsPerSecond(new Point((int) xwobble, (int) ywobble));
                    res.add(mov);
                    break;
                }
                case 1:
                case 2:
                case 6:
                case 12:
                case 13:
                case 16:
                case 18:
                case 19:
                case 22: {
                    short xwobble2 = lea.readShort();
                    short ywobble2 = lea.readShort();
                    byte newstate2 = lea.readByte();
                    short duration2 = lea.readShort();
                    StaticLifeMovement mov2 = new StaticLifeMovement((int) command, null, (int) duration2, (int) newstate2, 0);
                    mov2.setPixelsPerSecond(new Point((int) xwobble2, (int) ywobble2));
                    res.add(mov2);
                    break;
                }
                case 3:
                case 4:
                case 7:
                case 8:
                case 9:
                case 11: {
                    short xpos = lea.readShort();
                    short ypos = lea.readShort();
                    short unk2 = lea.readShort();
                    byte newstate3 = lea.readByte();
                    short duration3 = lea.readShort();
                    StaticLifeMovement mov3 = new StaticLifeMovement((int) command, new Point((int) xpos, (int) ypos), 0, (int) newstate3, 0);
                    mov3.setUnk(unk2);
                    res.add(mov3);
                    break;
                }
                case 10: {
                    byte newstate4 = 0;
                    short duration4 = 0;
                    int wui = lea.readByte();
                    StaticLifeMovement mov4 = new StaticLifeMovement((int) command, null, 0, 0, 0);
                    mov4.setWui(wui);
                    res.add(mov4);
                    break;
                }
                case 14: {
                    short xwobble2 = lea.readShort();
                    short ywobble2 = lea.readShort();
                    short fh2 = lea.readShort();
                    byte newstate3 = lea.readByte();
                    short duration3 = lea.readShort();
                    StaticLifeMovement mov3 = new StaticLifeMovement((int) command, null, (int) duration3, (int) newstate3, 0);
                    mov3.setPixelsPerSecond(new Point((int) xwobble2, (int) ywobble2));
                    mov3.setFh(fh2);
                    res.add(mov3);
                    break;
                }
                default: {
                    byte newstate4 = lea.readByte();
                    short duration4 = lea.readShort();
                    StaticLifeMovement mov5 = new StaticLifeMovement((int) command, null, (int) duration4, (int) newstate4, 0);
                    res.add(mov5);
                    break;
                }
            }
        }
        double skip = (double) lea.readByte();
        skip = Math.ceil(skip / 2.0);
        lea.skip((int) skip);
        if (numCommands != res.size()) {
            System.err.println("error in movement");
            return null;
        }
        return res;
    }

    public static void updatePosition(List<LifeMovementFragment> movement, AnimatedMapleMapObject target, int yoffset) {
        for (LifeMovementFragment move : movement) {
            if (move instanceof LifeMovement) {
                if (move instanceof StaticLifeMovement) {
                    Point position = ((StaticLifeMovement) move).getPosition();
                    if (position != null) {
                        Point point = position;
                        point.y += yoffset;
                        target.setPosition(position);
                    }
                }
                target.setStance(((StaticLifeMovement) move).getNewstate());
            }
        }
    }
}
